package com.vecspace.web.servlet.model;

import javax.servlet.http.HttpServletRequest;

import com.vecspace.core.support.AppProperties;
import com.vecspace.data.model.IPagination;
import com.vecspace.data.model.ListBO;
import com.vecspace.data.model.ResultObject;
import com.vecspace.database.model.QueryResult;
import com.vecspace.jsmodel.LayuiPlugin;
import com.vecspace.jsmodel.LigerGridPlugin;
import com.vecspace.msoffice.ExcelTemplate;
import com.vecspace.msoffice.ExportToHSSF;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.util.*;

public class HttpRequestUtil {
	/**
	 * 获取客户端的IP地址
	 * 功能描述：
	 * 在JSP里，获取客户端的IP地址的方法是：request.getRemoteAddr() ，这种方法在大部分情况下都是有效的。
	 * 但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。
	 * 如果使用了反向代理软件，将http://192.168.1.110:2046/ 的URL反向代理为http://www.xxx.com/ 的URL时，
	 * 用request.getRemoteAddr() 方法获取的IP地址是：127.0.0.1　或　192.168.1.110 ，而并不是客户端的真实ＩＰ。
	 * 经过代理以后，由于在客户端和服务之间增加了中间层，因此服务器无法直接拿到客户端的IP，服务器端应用也无法直接通过转发请求的地址返回给客户端。
	 * 但是在转发请求的HTTP头信息中，增加了X－FORWARDED－FOR信息。用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。
	 * 当我们访问http://www.xxx.com/index.jsp/ 时，其实并不是我们浏览器真正访问到了服务器上的index.jsp文件，
	 * 而是先由代理服务器去访问http://192.168.1.110:2046/index.jsp ，代理服务器再将访问到的结果返回给我们的浏览器，
	 * 因为是代理服务器去访问index.jsp的，所以index.jsp中通过request.getRemoteAddr() 的方法获取的IP实际上是代理服务器的地址，并不是客户端的IP地址。
	 * 
	 * 可是当我访问http://www.xxx.com/index.jsp/ 时，返回的IP地址始终是unknown，也并不是如上所示的127.0.0.1　或　192.168.1.110 了，
	 * 而我访问http://192.168.1.110:2046/index.jsp 时，则能返回客户端的真实IP地址，写了个方法去验证。原因出在了Squid上。
	 * squid.conf 的配制文件　forwarded_for 项默认是为on，如果 forwarded_for 设成了 off 　则：X-Forwarded-For: unknown
	 * @param request
	 * @return 
	 * @author: wanghua
	 */
	public static String getClientHost(javax.servlet.http.HttpServletRequest request){
	    String ip = request.getHeader("x-forwarded-for");
	    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
	        ip = request.getHeader("Proxy-Client-IP");
	    }
	    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
	        ip = request.getHeader("WL-Proxy-Client-IP");
	    }
	    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
	        ip = request.getRemoteAddr();
	    }
	    return ip.equals("0:0:0:0:0:0:0:1")?"127.0.0.1":ip;
	}
	
	/**获取访问地址（忽略项目名（即ContextPath））
	 * 比如项目 tweb
	 * http://localhost:8080/tweb/rest/base/test/info 返回 /rest/base/test/info
	 * 在web.xml中servlet的url-pattern 为 / 时(默认servlet)，有些web容器的getServletPath()返回空值（华胜信泰ToprowAS）
	 * @param request
	 * @return
	 * @author: wanghua
	 */
	public static String getFullPath(HttpServletRequest request) {
	    String uri = request.getRequestURI();
	    String contextPath = request.getContextPath();
	    if (StringUtils.length(contextPath) > 0) {
	        uri = StringUtils.substring(uri, contextPath.length());
	    }
	    return uri;
	}
	/**
     * 判断请求是否是AJAX请求
     * @param request
     * @return
     */
    public static boolean isAjaxRequest(HttpServletRequest request) {
        String header = request.getHeader("X-Requested-With");
        if (header != null && header.length() > 0) {
            if ("XMLHttpRequest".equalsIgnoreCase(header))
                return true;
        }
        return false;
    }

	public static boolean isMoblie(HttpServletRequest request) {
        Boolean isMoblie = false;
        String agentTag = request.getHeader("user-agent-tag");
        if("app".equals(agentTag))return true;
        String[] mobileAgents = { "android", "iphone", "phone", "mobile", "wap", "netfront", "java", "opera mobi",
                "opera mini", "ucweb", "windows ce", "symbian", "series", "webos", "sony", "blackberry", "dopod",
                "nokia", "samsung", "palmsource", "xda", "pieplus", "meizu", "midp", "cldc", "motorola", "foma",
                "docomo", "up.browser", "up.link", "blazer", "helio", "hosin", "huawei", "novarra", "coolpad", "webos",
                "techfaith", "palmsource", "alcatel", "amoi", "ktouch", "nexian", "ericsson", "philips", "sagem",
                "wellcom", "bunjalloo", "maui", "smartphone", "iemobile", "spice", "bird", "zte-", "longcos",
                "pantech", "gionee", "portalmmm", "jig browser", "hiptop", "benq", "haier", "^lct", "320x320",
                "240x320", "176x220", "w3c ", "acs-", "alav", "alca", "amoi", "audi", "avan", "benq", "bird", "blac",
                "blaz", "brew", "cell", "cldc", "cmd-", "dang", "doco", "eric", "hipt", "inno", "ipaq", "java", "jigs",
                "kddi", "keji", "leno", "lg-c", "lg-d", "lg-g", "lge-", "maui", "maxo", "midp", "mits", "mmef", "mobi",
                "mot-", "moto", "mwbp", "nec-", "newt", "noki", "oper", "palm", "pana", "pant", "phil", "play", "port",
                "prox", "qwap", "sage", "sams", "sany", "sch-", "sec-", "send", "seri", "sgh-", "shar", "sie-", "siem",
                "smal", "smar", "sony", "sph-", "symb", "t-mo", "teli", "tim-", "tosh", "tsm-", "upg1", "upsi", "vk-v",
                "voda", "wap-", "wapa", "wapi", "wapp", "wapr", "webc", "winw", "winw", "xda", "xda-",
                "Googlebot-Mobile" };
        String ua = request.getHeader("user-agent");
        if (org.apache.commons.lang3.StringUtils.isNotBlank(ua)) {
        	ua = ua.toLowerCase();
            for (String mobileAgent : mobileAgents) {
                if (ua.indexOf(mobileAgent) >= 0) {
                    isMoblie = true;
                    break;
                }
            }
        }

        return isMoblie;
    }

	/**将业务数据转为前端js组件定义的数据格式
	 *
	 * @param jsPluginType
	 * @param data
	 * @return
	 */
	public static Object trans2JSData(String jsPluginType,Object data){
		if(StringUtils.equalsIgnoreCase(jsPluginType, "LigerGrid")){
			if(data instanceof ListBO){
				LigerGridPlugin gridData = new LigerGridPlugin();
				ListBO<?> listBO = (ListBO<?>)data;
				int totalRows = 0;
				if(listBO.getPager() != null){
					totalRows = listBO.getPager().getTotalRows();
				}
				HashMap<?, ?> jsData = gridData.getGridData((Collection<?>)listBO.getItems(), totalRows);
				return jsData;
			}else if(data instanceof Collection){
				LigerGridPlugin gridData = new LigerGridPlugin();
				Object jsData = gridData.getGridData((Collection<?>)data, -1);
				return jsData;
			}
		}else if(StringUtils.equalsIgnoreCase(jsPluginType, "laytable")){
			if(data instanceof QueryResult) {
				LayuiPlugin layuiPlugin = new LayuiPlugin();
				QueryResult<?> queryResult = (QueryResult<?>)data;
				int totalRows = 0;
				if(queryResult.getPagination() != null){
					totalRows = queryResult.getPagination().getTotalRows();
				}
				HashMap<?, ?> jsData = layuiPlugin.getGridData((Collection<?>)queryResult.getEntities(), totalRows);
				return jsData;
			}else if(data instanceof ListBO){
				LayuiPlugin layuiPlugin = new LayuiPlugin();
				ListBO<?> listBO = (ListBO<?>)data;
				int totalRows = 0;
				if(listBO.getPager() != null){
					totalRows = listBO.getPager().getTotalRows();
				}
				HashMap<?, ?> jsData = layuiPlugin.getGridData((Collection<?>)listBO.getItems(), totalRows);
				return jsData;
			}if(data instanceof Collection){
				LayuiPlugin layuiPlugin = new LayuiPlugin();
				Object jsData = layuiPlugin.getGridData((Collection<?>)data, -1);
				return jsData;
			}
		}
		return data;
	}

	/**按Excel模板导出数据
	 *
	 * @param beanName
	 * @param methodPathName
	 * @param request
	 * @param excelTemplate
	 * @param exportData
	 * @param tenantId
	 * @return
	 * @throws Exception
	 */
	public static BinaryFile exportXlsData(String beanName, String methodPathName, HttpServletRequest request, ExcelTemplate excelTemplate, Object exportData, Long tenantId) throws Exception {
		BinaryFile responseData = null;
		if(exportData == null) exportData = new ArrayList<>();
		List<?> rows = null;
		Object data = null;

		if(exportData instanceof List){
			rows = (List<?>) exportData;
			Map<String, Object> map = new HashMap<>();
			map.put("total", rows.size());
			data  = map;
		}else if(exportData instanceof ListBO){
			ListBO listBO = (ListBO) exportData;
			rows = listBO.getItems();
			Map<String, Object> map = new HashMap<>();
			IPagination pager = listBO.getPager();
			if(pager != null) {
				map.put("currTotalRows", rows.size());
				map.put("pageIndex", pager.getPageIndex());
				map.put("pageSize", pager.getPageSize());
				map.put("totalPage", pager.getPages());
				map.put("totalRows", pager.getTotalRows());
			}
			data  = map;
		}else if(exportData instanceof ResultObject){
			ResultObject resultObject = (ResultObject) exportData;
			rows = resultObject.getRows();
			data = resultObject.getAttribute();
		}else if(exportData instanceof Map){
			rows = (List<Object>) ((Map<?, ?>) exportData).get("Rows");
		}else{
			data = exportData;
		}

		String templateExcelFileName = "";

		if(excelTemplate != null){
			templateExcelFileName = excelTemplate.templateFileName();
			if(StringUtils.isEmpty(templateExcelFileName)) {
				templateExcelFileName = request.getParameter("TemplateFileName");
			}
			if(StringUtils.isEmpty(templateExcelFileName)){
				templateExcelFileName = beanName + "_" + methodPathName + ".xls";
			}
			String tempFilePath = AppProperties.getTempExportPath();
			if(StringUtils.isEmpty(tempFilePath)) {
				tempFilePath = "./tempxls";
			}

			//按租户检索模板文件
			if(tenantId != null) {//如果获取到租户id,如果租户目录内存在导出模板，则使用租户自己的模板
				String tenantTempFilePath = tempFilePath + File.pathSeparator + tenantId + File.pathSeparator + templateExcelFileName;
				File fTenantTempFilePath = new File(tenantTempFilePath);
				if(fTenantTempFilePath.exists()) {
					tempFilePath = fTenantTempFilePath.getAbsolutePath();
				}
			}

			ExportToHSSF pExportToHSSF = new ExportToHSSF();
			String outFileName = pExportToHSSF.export2Excel(templateExcelFileName, tempFilePath, rows, data, excelTemplate.needMerge());
			String responseFileName = templateExcelFileName;
			if(StringUtils.isNotEmpty(excelTemplate.exportFileName())){
				responseFileName = excelTemplate.exportFileName()+".xls";
			}
			responseData = new BinaryFile();
			responseData.setFilePath(outFileName);
			responseData.setResponseFileName(responseFileName);
		}
		return responseData;
	}

	public static final String _401_JSON = "{'code': '403', 'msg': '访问被拒绝，客户端未登录！'}";
	public static final String _401_HTML = "<html><body><div style='text-align:center'><h1 style='margin-top: 10px;'>401 Unauthorized! 访问被拒绝，客户端未登录！</h1><hr><span></span></div></body></html>";

	public static final String _403_JSON = "{'code': '403', 'msg': '访问被拒绝，请求的接口未授权！'}";
	public static final String _403_HTML = "<html><body><div style='text-align:center'><h1 style='margin-top: 10px;'>403 Forbidden! 访问被拒绝，请求的接口未授权</h1><hr><span></span></div></body></html>";
}
